from rest_framework import serializers
from .models import CustomUser
from djoser.serializers import TokenCreateSerializer, UserSerializer, UserCreateSerializer
from rest_framework import exceptions
from rest_framework.validators import UniqueValidator
from utils.email_code import verify_email_code
from djoser.serializers import PasswordResetConfirmSerializer

from .utils import validate_verification_code


class CustomUniqueValidator(UniqueValidator):
    def __call__(self, value, serializer_field):
        self.message = '邮箱 %s 已经存在' % value
        return super().__call__(value, serializer_field)

class CustomUserCreateSerializer(UserCreateSerializer):
    email = serializers.EmailField(
        validators=[CustomUniqueValidator(queryset=CustomUser.objects.all())]
    )

    class Meta:
        model = CustomUser
        fields = ('id', 'username', 'email', 'password')

    # 新增代码
    # def create(self, validated_data):
    #     user = UserCreateSerializer.create(self, validated_data)
    #     # 写入到profile表
    #     profile = Profile(user=user)
    #     profile.save()
    #     return user
# class UserRegistrationSerializer(UserCreateSerializer):
#     email = serializers.EmailField(
#         validators=[CustomUniqueValidator(queryset=CustomUser.objects.all())]
#     )
#     password = serializers.CharField(
#         write_only=True,
#         style={'input_type': 'password'},
#         min_length=8,
#     )
#     re_password = serializers.CharField(
#         write_only=True,
#         style={'input_type': 'password'},
#     )
#     code = serializers.CharField(
#         write_only=True,
#         required=True,
#         error_messages={
#             'required': '验证码不能为空',
#             'blank': '验证码不能为空',
#         }
#     )
#
#     class Meta:
#         model = CustomUser
#         fields = ('id', 'username', 'email', 'password', 're_password', 'code')
#         extra_kwargs = {
#             'password': {'write_only': True}
#         }
#
#     def validate(self, attrs):
#         attrs = super().validate(attrs)
#         email = attrs.get('email')
#         code = attrs.get('code')
#
#         # 验证密码
#         if attrs.get('password') != attrs.get('re_password'):
#             raise serializers.ValidationError({"password": "两次输入的密码不一致"})
#
#         # 确保验证码存在
#         if not code:
#             raise serializers.ValidationError({"code": "验证码不能为空"})
#
#         # 验证验证码
#         if not verify_email_code(email, code):
#             raise serializers.ValidationError({"code": "验证码错误或已过期"})
#
#         # 成功验证后不需要保留验证码
#         attrs.pop('code', None)
#         return attrs
#
#     def create(self, validated_data):
#         # 移除re_password字段
#         validated_data.pop('re_password', None)
#         # 创建用户
#         user = CustomUser.objects.create_user(
#             username=validated_data['username'],
#             email=validated_data['email'],
#             password=validated_data['password']
#         )
#         return user


class CustomJWTSerializer(TokenCreateSerializer):
    def validate(self, attrs):
        attrs['username'] = attrs.get('email', '')  # 将email映射到username字段
        return super().validate(attrs)


class CustomUserSerializer(UserSerializer):
    date_joined = serializers.DateTimeField(format="%Y-%m-%d", read_only=True)
    class Meta(UserSerializer.Meta):
        model = CustomUser
        fields = ('id', 'username', 'email', 'slug_user', 'avatar', 'phone', 'bio', 'date_joined')  # 添加更多自定义字段


class PasswordChangeSerializer(serializers.Serializer):
    old_password = serializers.CharField(
        style={'input_type': 'password'},
        required=True,
        error_messages={
            'required': '旧密码不能为空'
        }
    )
    new_password = serializers.CharField(
        style={'input_type': 'password'},
        required=True,
        min_length=8,
        error_messages={
            'required': '新密码不能为空',
            'min_length': '密码长度至少为8个字符'
        }
    )
    re_new_password = serializers.CharField(
        style={'input_type': 'password'},
        required=True,
        error_messages={
            'required': '确认密码不能为空'
        }
    )

    def validate(self, attrs):
        if attrs['new_password'] != attrs['re_new_password']:
            raise serializers.ValidationError({"re_new_password": "两次输入的新密码不一致"})
        return attrs


class ForgetPasswordSerializer(serializers.Serializer):
    email = serializers.EmailField(
        required=True,
        error_messages={
            'required': '邮箱不能为空',
            'invalid': '请输入有效的邮箱地址'
        }
    )
    code = serializers.CharField(
        write_only=True,
        required=True,
        error_messages={
            'required': '验证码不能为空',
            'blank': '验证码不能为空',
        }
    )
    new_password = serializers.CharField(
        write_only=True,
        required=True,
        min_length=8,
        error_messages={
            'required': '新密码不能为空',
            'min_length': '密码长度至少为8个字符'
        }
    )
    re_new_password = serializers.CharField(
        write_only=True,
        required=True,
        error_messages={
            'required': '确认密码不能为空'
        }
    )

    def validate(self, attrs):
        email = attrs.get('email')
        code = attrs.get('code')

        # 验证密码
        if attrs.get('new_password') != attrs.get('re_new_password'):
            raise serializers.ValidationError({"new_password": "两次输入的密码不一致"})

        # 验证验证码
        if not verify_email_code(email, code):
            raise serializers.ValidationError({"code": "验证码错误或已过期"})

        return attrs


class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = CustomUser
        fields = ('id', 'username', 'avatar', 'bio')


class CustomPasswordResetConfirmSerializer(PasswordResetConfirmSerializer):
    # 移除不需要的字段
    uid = None
    token = None

    code = serializers.CharField(
        required=True,
        error_messages={
            'required': '验证码不能为空',
            'blank': '验证码不能为空',
        }
    )
    email = serializers.EmailField(
        required=True,
        error_messages={
            'required': '邮箱不能为空',
            'invalid': '请输入有效的邮箱地址'
        }
    )
    new_password = serializers.CharField(
        write_only=True,
        required=True,
        min_length=8,
        error_messages={
            'required': '新密码不能为空',
            'min_length': '密码长度至少为8个字符'
        }
    )
    re_new_password = serializers.CharField(
        write_only=True,
        required=True,
        error_messages={
            'required': '确认密码不能为空'
        }
    )

    def validate_email(self, value):
        try:
            self.user = CustomUser.objects.get(email=value)
        except CustomUser.DoesNotExist:
            raise serializers.ValidationError("该邮箱未注册")
        return value

    def validate(self, attrs):
        # 验证码校验
        if not verify_email_code(attrs['email'], attrs['code']):
            raise serializers.ValidationError({"code": "验证码错误或已过期"})
            
        # 验证两次密码是否一致
        if attrs.get('new_password') != attrs.get('re_new_password'):
            raise serializers.ValidationError({"new_password": "两次输入的密码不一致"})
            
        return attrs

    def save(self):
        self.user.set_password(self.validated_data["new_password"])
        self.user.save()